import os
import time
import re
import EXIF
import sys


def get_date_from_filename(file):
    match = re.search(r'(20\d\d)(\d\d)(\d\d)_(\d\d)(\d\d)(\d\d)', file)
    if not match:
        match = re.search(r'(20\d\d)-(\d\d)-(\d\d) (\d\d).(\d\d).(\d\d)', file)
        if not match:
            return None
    date = (match.group(1), match.group(2), match.group(3), match.group(4), match.group(5), match.group(6))
    return date


def fill_date(date, dst):
    dst2 = [dst[i] for i in range(len(dst))]
    dst2[0] = int(date[0])
    dst2[1] = int(date[1])
    dst2[2] = int(date[2])
    dst2[3] = int(date[3])
    dst2[4] = int(date[4])
    dst2[5] = int(date[5])

    dst_time = time.mktime(dst2)

    return dst_time


def get_exif_date(file):
    try:
        with open(file, 'rb') as fh:
            tags = EXIF.process_file(fh, stop_tag="EXIF DateTimeOriginal")
            dateTaken = tags["EXIF DateTimeOriginal"]
            match = re.search(r'(20\d\d):(\d\d):(\d\d) (\d\d):(\d\d):(\d\d)', str(dateTaken))
            if match:
                date = (match.group(1), match.group(2), match.group(3), match.group(4), match.group(5), match.group(6))
                return date
    except Exception as ex:
        # print ex
        pass
    return None


def rename(date, root, file, do_rename=False):
    is_match = True
    splitfile = os.path.splitext(file)
    match = re.search(r'(20\d\d)(\d\d)(\d\d)_(\d\d)(\d\d)(\d\d)', splitfile[0])
    new_date = ('%s%s%s_%s%s%s' % date)
    if not match:
        match = re.search(r'(20\d\d)-(\d\d)-(\d\d) (\d\d).(\d\d).(\d\d)', splitfile[0])
        new_date = ('%s-%s-%s %s.%s.%s' % date)
        if not match:
            is_match = False

    if is_match:
        new_file = re.sub(match.group(), new_date, splitfile[0])
    else:
        match = re.search(r'(\d+)', splitfile[0])
        if match:
            new_file = re.sub(match.group(1), ('%s%s%s_%s%s%s' % date), splitfile[0])
        else:
            new_file = splitfile[0] + ('%s%s%s_%s%s%s' % date)
    new_file_full = new_file + splitfile[-1]
    # print '---old:', file, 'new:', new_file_full
    if not new_file_full == file:
        for post_id in range(10):
            if post_id > 0:
                new_file_full = new_file + ('_%d' % (post_id))+ splitfile[-1]
            if not os.path.exists(os.path.join(root, new_file_full)):
                break
        if do_rename:
            try:
                os.rename(os.path.join(root, file), os.path.join(root, new_file_full))
                print 'Rename (done): %s ---> %s' % (file, new_file_full)
                return new_file_full
            except Exception as ex:
                print '--- Rename (failed): %s ---> %s' % (file, new_file_full), 'Exception Info:', ex
        else:
            print 'Rename suggestion: %s ---> %s' % (file, new_file_full)
    return file


if __name__ == '__main__':

    path = '../Camera/'

    if len(sys.argv) > 1 and sys.argv[1] is not None:
        path = sys.argv[1]

    do_rename = False
    if len(sys.argv) > 2 and sys.argv[2] is not None and sys.argv[2] == 'rename':
        do_rename = True

    for root, dirs, files in os.walk(path):
        for file in files:

            ext = os.path.splitext(file)[-1].lower()
            if ext not in ('.jpg', '.jpeg', '.png', '.mp4', '.mov'):
                continue

            stat = os.stat(os.path.join(root, file))
            at = time.localtime(stat.st_atime)  # last access time
            mt = time.localtime(stat.st_mtime)  # last modify time

            # print file, at, mt

            new_date = None
            date = get_date_from_filename(file)
            exif_date = get_exif_date(os.path.join(root, file))

            if date is not None:
                new_date = date
            if exif_date is not None:
                # print 'EXIF date:', exif_date, file
                new_date = exif_date

            if new_date is None:
                print 'Cannot find date:', file
                continue
            else:
                file = rename(new_date, root, file, do_rename)

            new_at = fill_date(new_date, at)
            new_mt = new_at

            # print new_at
            # print new_mt
            os.utime(os.path.join(root, file), (new_at, new_mt))

    print 'done!'
